{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Title: #Equal Rational Numbers"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Difficulty: #Hard"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Category Title: #Algorithms"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Tag Slug: #math #string"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Name Translated: #数学 #字符串"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Solution Name: isRationalEqual"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Translated Title: #相等的有理数"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Translated Content:\n",
    "<p>给定两个字符串&nbsp;<code>s</code>&nbsp;和&nbsp;<code>t</code>&nbsp;，每个字符串代表一个非负有理数，只有当它们表示相同的数字时才返回 <code>true</code>&nbsp;。字符串中可以使用括号来表示有理数的重复部分。</p>\n",
    "\n",
    "<p><strong>有理数</strong>&nbsp;最多可以用三个部分来表示：<em>整数部分</em>&nbsp;<code>&lt;IntegerPart&gt;</code>、<em>小数非重复部分</em>&nbsp;<code>&lt;NonRepeatingPart&gt;</code>&nbsp;和<em>小数重复部分</em>&nbsp;<code>&lt;(&gt;&lt;RepeatingPart&gt;&lt;)&gt;</code>。数字可以用以下三种方法之一来表示：</p>\n",
    "\n",
    "<ul>\n",
    "\t<li><code>&lt;IntegerPart&gt;</code>&nbsp;\n",
    "\n",
    "\t<ul>\n",
    "\t\t<li>例：&nbsp;<code>0</code>&nbsp;,<code>12</code>&nbsp;和&nbsp;<code>123</code>&nbsp;</li>\n",
    "\t</ul>\n",
    "\t</li>\n",
    "\t<li><code>&lt;IntegerPart&gt;&lt;.&gt;&lt;NonRepeatingPart&gt;</code>\n",
    "\t<ul>\n",
    "\t\t<li>例： <code>0.5<font color=\"#333333\"><font face=\"Helvetica Neue, Helvetica, Arial, sans-serif\"><span style=\"font-size:14px\"><span style=\"background-color:#ffffff\">&nbsp;, </span></span></font></font></code><font color=\"#333333\"><font face=\"Helvetica Neue, Helvetica, Arial, sans-serif\"><span style=\"font-size:14px\"><span style=\"background-color:#ffffff\"><code>1.</code>&nbsp;,&nbsp;</span></span></font></font><code>2.12</code>&nbsp;和&nbsp;<code>123.0001</code></li>\n",
    "\t</ul>\n",
    "\t</li>\n",
    "\t<li><code>&lt;IntegerPart&gt;&lt;.&gt;&lt;NonRepeatingPart&gt;&lt;(&gt;&lt;RepeatingPart&gt;&lt;)&gt;</code>&nbsp;\n",
    "\t<ul>\n",
    "\t\t<li>例： <code>0.1(6)</code> ， <code>1.(9)</code>， <code>123.00(1212)</code></li>\n",
    "\t</ul>\n",
    "\t</li>\n",
    "</ul>\n",
    "\n",
    "<p>十进制展开的重复部分通常在一对圆括号内表示。例如：</p>\n",
    "\n",
    "<ul>\n",
    "\t<li><code>1 / 6 = 0.16666666... = 0.1(6) = 0.1666(6) = 0.166(66)</code></li>\n",
    "</ul>\n",
    "\n",
    "<p>&nbsp;</p>\n",
    "\n",
    "<p><strong>示例 1：</strong></p>\n",
    "\n",
    "<pre>\n",
    "<strong>输入：</strong>s = \"0.(52)\", t = \"0.5(25)\"\n",
    "<strong>输出：</strong>true\n",
    "<strong>解释：</strong>因为 \"0.(52)\" 代表 0.52525252...，而 \"0.5(25)\" 代表 0.52525252525.....，则这两个字符串表示相同的数字。\n",
    "</pre>\n",
    "\n",
    "<p><strong>示例 2：</strong></p>\n",
    "\n",
    "<pre>\n",
    "<strong>输入：</strong>s = \"0.1666(6)\", t = \"0.166(66)\"\n",
    "<strong>输出：</strong>true\n",
    "</pre>\n",
    "\n",
    "<p><strong>示例 3：</strong></p>\n",
    "\n",
    "<pre>\n",
    "<strong>输入：</strong>s = \"0.9(9)\", t = \"1.\"\n",
    "<strong>输出：</strong>true\n",
    "<strong>解释：</strong>\"0.9(9)\" 代表 0.999999999... 永远重复，等于 1 。[<a href=\"https://baike.baidu.com/item/0.999…/5615429?fr=aladdin\" target=\"_blank\">有关说明，请参阅此链接</a>]\n",
    "\"1.\" 表示数字 1，其格式正确：(IntegerPart) = \"1\" 且 (NonRepeatingPart) = \"\" 。</pre>\n",
    "\n",
    "<p>&nbsp;</p>\n",
    "\n",
    "<p><strong>提示：</strong></p>\n",
    "\n",
    "<ul>\n",
    "\t<li>每个部分仅由数字组成。</li>\n",
    "\t<li>整数部分&nbsp;<code>&lt;IntegerPart&gt;</code>&nbsp;不会以零开头。（零本身除外）</li>\n",
    "\t<li><code>1 &lt;= &lt;IntegerPart&gt;.length &lt;= 4 </code></li>\n",
    "\t<li><code>0 &lt;= &lt;NonRepeatingPart&gt;.length &lt;= 4 </code></li>\n",
    "\t<li><code>1 &lt;= &lt;RepeatingPart&gt;.length &lt;= 4 </code></li>\n",
    "</ul>\n",
    "<span style=\"display:block\"><span style=\"height:0px\"><span style=\"position:absolute\">​​​​​</span></span></span>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Description: [equal-rational-numbers](https://leetcode.cn/problems/equal-rational-numbers/description/)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Solutions: [equal-rational-numbers](https://leetcode.cn/problems/equal-rational-numbers/solutions/)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "test_cases = ['\"0.(52)\"\\n\"0.5(25)\"', '\"0.1666(6)\"\\n\"0.166(66)\"', '\"0.9(9)\"\\n\"1.\"']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "from fractions import Fraction\n",
    "\n",
    "class Solution(object):\n",
    "    def isRationalEqual(self, S, T):\n",
    "        # def convert(S):\n",
    "        #     if '.' not in S:\n",
    "        #         return Fraction(int(S), 1)\n",
    "        #     i = S.index('.')\n",
    "        #     ans = Fraction(int(S[:i]), 1)\n",
    "        #     S = S[i+1:]\n",
    "        #     if '(' not in S:\n",
    "        #         if S:\n",
    "        #             ans += Fraction(int(S), 10 ** len(S))\n",
    "        #         return ans\n",
    "\n",
    "        #     i = S.index('(')\n",
    "        #     if i:\n",
    "        #         ans += Fraction(int(S[:i]), 10 ** i)\n",
    "        #     S = S[i+1:-1]\n",
    "        #     j = len(S)\n",
    "        #     ans += Fraction(int(S), 10**i * (10**j - 1))\n",
    "        #     return ans\n",
    "        def convert(S):\n",
    "            if '.' not in S:\n",
    "                return Fraction(int(S), 1)\n",
    "            i = S.index('.')\n",
    "            ans = Fraction(int(S[:i]), 1)\n",
    "            S = S[i + 1:]\n",
    "            if '(' not in S:\n",
    "                if S:\n",
    "                    ans += Fraction(int(S), 10 ** (len(S)))\n",
    "                return ans\n",
    "            i = S.index('(')\n",
    "            if i:\n",
    "                ans += Fraction(int(S[:i]), 10 ** i)\n",
    "            S = S[i + 1: -1]\n",
    "            j = len(S)\n",
    "            ans += Fraction(int(S), 10 ** i * (10 ** j - 1))\n",
    "            return ans\n",
    "        return convert(S) == convert(T)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def isRationalEqual(self, s: str, t: str) -> bool:\n",
    "        if not '.' in s:\n",
    "            s+='.'\n",
    "        if not '.' in t:\n",
    "            t+='.'\n",
    "        a=s.index('.')\n",
    "        b=t.index('.')\n",
    "        m=int(s[:a])\n",
    "        n=int(t[:b])\n",
    "        if abs(m-n)>1:\n",
    "            return False\n",
    "        s=s[a+1::]\n",
    "        t=t[b+1::]\n",
    "        if not s:\n",
    "            m+=0\n",
    "        elif ')' in s:\n",
    "            a=s.index('(')\n",
    "            c=s.index(')')\n",
    "            if s[:a]:\n",
    "                m+=int(s[:a])*10**(-1*a)\n",
    "            m+=int(s[a+1:c])/(10**(c-a-1)-1)/10**(a)\n",
    "        else:\n",
    "            m+=int(s)/10**(len(s))\n",
    "        if not t:\n",
    "            n+=0\n",
    "        elif ')' in t:\n",
    "            b=t.index('(')\n",
    "        \n",
    "            d=t.index(')')\n",
    "            if t[:b]:\n",
    "                n+=int(t[:b])*10**(-1*b)\n",
    "            n+=int(t[b+1:d])/(10**(d-b-1)-1)/10**b\n",
    "        else:\n",
    "            n+=int(t)/10**(len(t))\n",
    "        return abs(int(m*10**10)-int(n*10**10))<=1\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def isRationalEqual(self, S: str, T: str) -> bool:\n",
    "        def conv(s):\n",
    "            if '(' in s:\n",
    "                idx = s.index('(')\n",
    "                return float(s[:idx] + s[idx+1:-1] * 20)\n",
    "            return float(s)\n",
    "\n",
    "        return conv(S) == conv(T)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def isRationalEqual(self, S, T):\n",
    "        \"\"\"\n",
    "        :type S: str\n",
    "        :type T: str\n",
    "        :rtype: bool\n",
    "        \"\"\"\n",
    "        s=self.handle(S)\n",
    "        t = self.handle(T)\n",
    "        return abs(float(s)-float(t))<0.00000001\n",
    "    def handle(self,s):\n",
    "        p = s.find('(')\n",
    "        if p!=-1:\n",
    "            cycle = s[p+1:-1]\n",
    "            s = s[:p]+cycle*15\n",
    "        return s"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def isRationalEqual(self, s: str, t: str) -> bool:\n",
    "        if s[-1] == ')':\n",
    "            a, b = s.split('(')\n",
    "            b = b[:-1] \n",
    "        else:\n",
    "            a = s\n",
    "            b = ''\n",
    "\n",
    "        if  t[-1] == ')':\n",
    "            c, d = t.split('(')\n",
    "            d = d[:-1]\n",
    "        else:\n",
    "            c = t\n",
    "            d = ''\n",
    "       \n",
    "        m1 = len(b)\n",
    "        m2 = len(d)\n",
    "        n = max(m1,m2)\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "        for i in range(20*n):\n",
    "            a = a+b\n",
    "        svalue = float(a)         \n",
    "        \n",
    "        for j in range(20*n):\n",
    "            c = c+d\n",
    "        tvalue = float(c)\n",
    "        print(a,c)\n",
    "        return True if abs(svalue-tvalue)<10**(-17) else False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "from fractions import Fraction\n",
    "\n",
    "class Solution(object):\n",
    "    def isRationalEqual(self, S, T):\n",
    "        def convert(S):\n",
    "            if '.' not in S:\n",
    "                return Fraction(int(S), 1)\n",
    "            i = S.index('.')\n",
    "            ans = Fraction(int(S[:i]), 1)\n",
    "            S = S[i+1:]\n",
    "            if '(' not in S:\n",
    "                if S:\n",
    "                    ans += Fraction(int(S), 10 ** len(S))\n",
    "                return ans\n",
    "\n",
    "            i = S.index('(')\n",
    "            if i:\n",
    "                ans += Fraction(int(S[:i]), 10 ** i)\n",
    "            S = S[i+1:-1]\n",
    "            j = len(S)\n",
    "            ans += Fraction(int(S), 10**i * (10**j - 1))\n",
    "            return ans\n",
    "\n",
    "        return convert(S) == convert(T)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "from fractions import Fraction\n",
    "class Solution:\n",
    "    def isRationalEqual(self, s: str, t: str) -> bool:\n",
    "        def get_factor(num):\n",
    "            if '.' not in num:\n",
    "                return int(num)\n",
    "            else:\n",
    "                idx = num.index('.')\n",
    "                res = Fraction(int(num[ : idx] or 0), 1)\n",
    "                num = num[idx + 1 : ]\n",
    "                if '(' not in num:\n",
    "                    res += Fraction(int(num or 0), 10 ** len(num))\n",
    "                else:\n",
    "                    idx = num.index('(')\n",
    "                    res += Fraction(int(num[:idx] or 0) , 10 ** idx)\n",
    "                    num = num[idx + 1 : - 1]\n",
    "                    res += Fraction(int(num or 0), 10 ** idx * (10 ** len(num) - 1))\n",
    "            return res \n",
    "        return get_factor(s) == get_factor(t)\n",
    "\n",
    "\n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def isRationalEqual(self, s: str, t: str) -> bool:\n",
    "\n",
    "        newli = []\n",
    "        for li in [s, t]:\n",
    "\n",
    "            # print('---- ', li)\n",
    "            if len(li.split('(')) > 1:\n",
    "                float_part, xh_part = li.split('(')\n",
    "            else:\n",
    "                float_part = li.split('(')[0]\n",
    "                xh_part = '0'\n",
    "            float_part = float_part if '.' in float_part else f\"{float_part}.\"\n",
    "            xh_part = xh_part.replace(')', '')\n",
    "            # print(float_part, xh_part)\n",
    "\n",
    "            if len(xh_part) > 1:\n",
    "                i = 1\n",
    "                while i <= len(xh_part)/2:\n",
    "                    if xh_part[0] == xh_part[i]:\n",
    "                        tmp = [True if len(x) == 0 else False for x in xh_part.split(xh_part[0:i])]\n",
    "                        if all(tmp):\n",
    "                            xh_part = xh_part[0:i]\n",
    "                            break\n",
    "                    i += 1\n",
    "                    continue\n",
    "\n",
    "            while float_part[-1] == xh_part[-1]:\n",
    "                float_part = float_part[:-1]\n",
    "                # xh_part = xh_part[::-1]\n",
    "                xh_part = f\"{xh_part[-1]}{xh_part[:-1]}\"\n",
    "            if xh_part == '9':\n",
    "                # print(f\"[debug] {float(float_part)}, \", 10**(-len(float_part.split('.')[1])), float(float_part) + 10**(-len(float_part.split('.')[1])))\n",
    "                # tmp_float_part = f\"{float(float_part) + 10**(-len(float_part.split('.')[1]))}\"\n",
    "                tmp_float_part = f\"{int(float_part.replace('.', '')) + 1}\"\n",
    "                tmp_float_part = tmp_float_part.zfill(\n",
    "                    max(len(tmp_float_part), len(float_part)-1)\n",
    "                    )\n",
    "                tmp_len = len(float_part.split('.')[1])\n",
    "                # print(f'[debug] {tmp_float_part}, {tmp_len}')\n",
    "                float_part = f\"{tmp_float_part[:(len(tmp_float_part)-tmp_len)]}.{tmp_float_part[(len(tmp_float_part)-tmp_len):]}\"\n",
    "                float_part = float_part if float_part[-2:] != '.0' else float_part[:-1]\n",
    "                xh_part = '0'\n",
    "                \n",
    "            # print(float_part, xh_part)\n",
    "            \n",
    "            newli.append(f\"{float_part}{'.' if '.' not in float_part else ''}({xh_part})\")\n",
    "\n",
    "        if newli[0] == newli[1]:\n",
    "            return True\n",
    "        return False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def isRationalEqual(self, s: str, t: str) -> bool:\n",
    "        def g(a):\n",
    "            if \".\" in a:\n",
    "                x, p = a.split(\".\")\n",
    "                if \"(\" in p:\n",
    "                    y, z = p.split(\"(\")\n",
    "                    z = z[:-1]\n",
    "                    if set(z) == {\"9\"}:\n",
    "                        z = \"0\"\n",
    "                        if set(y) == {\"9\"} or not y:\n",
    "                            y = \"0\"\n",
    "                            x = str(int(x) + 1)\n",
    "                        else:\n",
    "                            c = len(y)\n",
    "                            y = str(int(y) + 1).rjust(c, \"0\")\n",
    "                else: y, z = p, \"0\"\n",
    "            else:\n",
    "                x, y, z = a, \"0\", \"0\"\n",
    "            return [x,y,z]\n",
    "        sl, tl = g(s), g(t)\n",
    "        m, n = len(sl[1]), len(tl[1])\n",
    "        if m > n: m, n, sl, tl = n, m, tl, sl\n",
    "        # print(sl, tl)\n",
    "        if len(sl[2]):\n",
    "            for i in range(n-m):\n",
    "                v = sl[2][0]\n",
    "                sl[1] += v\n",
    "                sl[2] = sl[2][1:]+v\n",
    "        # print(sl, tl)\n",
    "        return sl[0] == tl[0] and sl[1] == tl[1] and sl[2]*len(tl[2]) == tl[2]*(len(sl[2]))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def isRationalEqual(self, s: str, t: str) -> bool:\n",
    "        def update(nr, r):\n",
    "            if not nr or not r: return nr, r\n",
    "            st, n1, n2 = 0, len(nr), len(r)\n",
    "            while True:\n",
    "                if nr[n1 - 1 - st] != r[n2 - 1 - st]: break\n",
    "                st += 1\n",
    "                if st >= n1 or st >= n2: break\n",
    "            nr1, r1 = nr[: n1 - st], nr[n1 - st:] + r[: n2 - st]\n",
    "            if st == 0 or not nr1 or not r1: return nr1, r1\n",
    "            return update(nr1, r1)\n",
    "        def get(word):\n",
    "            parts = word.split('.')\n",
    "            if len(parts) == 1: return word\n",
    "            if not parts[1]: return word[: -1]\n",
    "            p0, p1 = parts\n",
    "            n, idx = len(p1), 0\n",
    "            while idx < n:\n",
    "                if p1[idx] == '(': break\n",
    "                idx += 1\n",
    "            nr, r = p1[: idx], p1[idx + 1: n - 1]\n",
    "            n1 = len(r)\n",
    "            for i in range(1, n1):\n",
    "                if n1 % i == 0 and (n1 // i) * r[: i] == r:\n",
    "                    r = r[: i]\n",
    "                    break\n",
    "            nr, r = update(nr, r)\n",
    "            if not nr:\n",
    "                if not r or r == '0': return p0\n",
    "                if r == '9': return str(int(p0) + 1)\n",
    "                return p0 + '.' + '(' + r + ')'\n",
    "            if not r:\n",
    "                if nr == '0' * len(nr): return p0\n",
    "                return p0 + '.' + nr\n",
    "            if r == '9':\n",
    "                n2 = len(nr)\n",
    "                tmp = str(int(nr) + 1)\n",
    "                return p0 + '.' + '0' * (n2 - len(tmp)) + tmp\n",
    "            if r == '0':\n",
    "                if nr == '0' * len(nr): return p0\n",
    "                return p0 + '.' + nr\n",
    "            return p0 + '.' + nr +'(' + r + ')'\n",
    "        return get(s) == get(t)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "from fractions import Fraction\n",
    "class Solution:\n",
    "    def isRationalEqual(self, s: str, t: str) -> bool:\n",
    "        def trans(string):\n",
    "           if string[-1] != ')':\n",
    "               return Fraction(string)\n",
    "           else:\n",
    "               a, b = string.split('(')\n",
    "               b = b[:-1]\n",
    "               inte, nonrep = a.split('.')\n",
    "               k = len(nonrep)\n",
    "               l = len(b)\n",
    "               return int(inte) + Fraction(int('0'+nonrep), 10**k) + Fraction(int(b), 10**(k)*(10**l-1))    \n",
    "        print(trans(s), trans(t))   \n",
    "        return trans(s) == trans(t)\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "from fractions import Fraction\n",
    "\n",
    "class Solution(object):\n",
    "    def isRationalEqual(self, S, T):\n",
    "        def convert(S):\n",
    "            if '.' not in S:\n",
    "                return Fraction(int(S), 1)\n",
    "            i = S.index('.')\n",
    "            ans = Fraction(int(S[:i]), 1)\n",
    "            S = S[i+1:]\n",
    "            if '(' not in S:\n",
    "                if S:\n",
    "                    ans += Fraction(int(S), 10 ** len(S))\n",
    "                return ans\n",
    "\n",
    "            i = S.index('(')\n",
    "            if i:\n",
    "                ans += Fraction(int(S[:i]), 10 ** i)\n",
    "            S = S[i+1:-1]\n",
    "            j = len(S)\n",
    "            ans += Fraction(int(S), 10**i * (10**j - 1))\n",
    "            return ans\n",
    "\n",
    "        return convert(S) == convert(T)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "\n",
    "    def isRationalEqual(self, s: str, t: str) -> bool:\n",
    "\n",
    "        def parse(ss):\n",
    "            i_dot = ss.find('.')\n",
    "            intPart = ss[:i_dot] if i_dot != -1 else ss\n",
    "            i_lq, i_rq = ss.find('('), ss.find(')')\n",
    "            nrPart, rPart = '', ''\n",
    "            if i_dot != -1:\n",
    "                if i_lq != -1 and i_rq != -1:\n",
    "                    rPart = ss[i_lq + 1:i_rq]\n",
    "                    nrPart = ss[i_dot + 1:i_lq]\n",
    "                else:\n",
    "                    nrPart = ss[i_dot + 1:]\n",
    "            lnr = len(nrPart)\n",
    "            a = b = 0\n",
    "            if nrPart:\n",
    "                a, b = int(nrPart), 10**lnr\n",
    "            if rPart:\n",
    "                lr = len(rPart)\n",
    "                a, b = int(rPart), 10**lr - 1\n",
    "                a += int(nrPart) * b if nrPart else 0\n",
    "                b *= 10**lnr\n",
    "                a, b = a // gcd(a, b), b // gcd(a, b)\n",
    "            return int(intPart), a, b\n",
    "\n",
    "        def calc(num, a, b):\n",
    "            if a == 0 or b == 0: return num\n",
    "            return num + a / b\n",
    "\n",
    "        # print(parse(s), parse(t))\n",
    "        return calc(*parse(s)) == calc(*parse(t))\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "from fractions import Fraction\n",
    "\n",
    "class Solution:\n",
    "    def isRationalEqual(self, S: str, T: str) -> bool:\n",
    "        def convert(S):\n",
    "            if '.' not in S:\n",
    "                return Fraction(int(S), 1)\n",
    "            i = S.index('.')\n",
    "            ans = Fraction(int(S[:i]), 1)\n",
    "            S = S[i+1:]\n",
    "            if '(' not in S:\n",
    "                if S:\n",
    "                    ans += Fraction(int(S), 10 ** len(S))\n",
    "                return ans\n",
    "\n",
    "            i = S.index('(')\n",
    "            if i:\n",
    "                ans += Fraction(int(S[:i]), 10 ** i)\n",
    "            S = S[i+1:-1]\n",
    "            j = len(S)\n",
    "            ans += Fraction(int(S), 10**i * (10**j - 1))\n",
    "            return ans\n",
    "\n",
    "        return convert(S) == convert(T)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def isRationalEqual(self, s: str, t: str) -> bool:\n",
    "        def g(a):\n",
    "            if \".\" in a:\n",
    "                x, p = a.split(\".\")\n",
    "                if \"(\" in p:\n",
    "                    y, z = p.split(\"(\")\n",
    "                    z = z[:-1]\n",
    "                    c = 10 ** (len(z)) - 1\n",
    "                    a, b = int(x+y) * c + int(z), c * 10 ** (len(y))\n",
    "                else: a, b = int(x+p), 10 ** len(p)\n",
    "            else: a, b = int(a), 1\n",
    "            c = gcd(a,b)\n",
    "            return a//c, b//c\n",
    "        return g(s) == g(t)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def isRationalEqual(self, S: str, T: str) -> bool:\n",
    "        def conv(s):\n",
    "            if '(' in s:\n",
    "                idx = s.index('(')\n",
    "                return float(s[:idx] + s[idx+1:-1] * 20)\n",
    "            return float(s)\n",
    "\n",
    "        return conv(S) == conv(T)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def isRationalEqual(self, s: str, t: str) -> bool:\n",
    "        def update(nr, r):\n",
    "            if not nr or not r: return nr, r\n",
    "            st, n1, n2 = 0, len(nr), len(r)\n",
    "            while True:\n",
    "                if nr[n1 - 1 - st] != r[n2 - 1 - st]: break\n",
    "                st += 1\n",
    "                if st >= n1 or st >= n2: break\n",
    "            nr1, r1 = nr[: n1 - st], nr[n1 - st:] + r[: n2 - st]\n",
    "            if st == 0 or not nr1 or not r1: return nr1, r1\n",
    "            return update(nr1, r1)\n",
    "        def get(word):\n",
    "            parts = word.split('.')\n",
    "            if len(parts) == 1: return word\n",
    "            if not parts[1]: return word[: -1]\n",
    "            p0, p1 = parts\n",
    "            n, idx = len(p1), 0\n",
    "            while idx < n:\n",
    "                if p1[idx] == '(': break\n",
    "                idx += 1\n",
    "            nr, r = p1[: idx], p1[idx + 1: n - 1]\n",
    "            n1 = len(r)\n",
    "            for i in range(1, n1):\n",
    "                if n1 % i == 0 and (n1 // i) * r[: i] == r:\n",
    "                    r = r[: i]\n",
    "                    break\n",
    "            nr, r = update(nr, r)\n",
    "            if not nr:\n",
    "                if not r or r == '0': return p0\n",
    "                if r == '9': return str(int(p0) + 1)\n",
    "                return p0 + '.' + '(' + r + ')'\n",
    "            if not r:\n",
    "                if nr == '0' * len(nr): return p0\n",
    "                return p0 + '.' + nr\n",
    "            if r == '9':\n",
    "                n2 = len(nr)\n",
    "                tmp = str(int(nr) + 1)\n",
    "                return p0 + '.' + '0' * (n2 - len(tmp)) + tmp\n",
    "            if r == '0':\n",
    "                if nr == '0' * len(nr): return p0\n",
    "                return p0 + '.' + nr\n",
    "            return p0 + '.' + nr +'(' + r + ')'\n",
    "        return get(s) == get(t)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def isRationalEqual(self, s: str, t: str) -> bool:\n",
    "        def f(ss):\n",
    "            n = len(ss)\n",
    "            l=r=-1\n",
    "            for i in range(n):\n",
    "                if ss[i] == '(':\n",
    "                    l = i\n",
    "                if ss[i] == ')':\n",
    "                    r = i\n",
    "            return [l,r]\n",
    "        if '(' in s:\n",
    "            l,r = f(s)\n",
    "            s = s[:l]+s[l+1:r]*32\n",
    "        if '(' in t:\n",
    "            l,r = f(t)\n",
    "            t = t[:l]+t[l+1:r]*32\n",
    "        print(float(s),float(t))\n",
    "        return float(s) == float(t)\n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "from fractions import Fraction\n",
    "\n",
    "class Solution:\n",
    "    def isRationalEqual(self, S: str, T: str) -> bool:\n",
    "        def convert(S): # 123.00(1212)\n",
    "            if '.' not in S:\n",
    "                return Fraction(int(S), 1)\n",
    "            i = S.index('.') # i = 3\n",
    "            ans = Fraction(int(S[:i]), 1) # Fraction(123, 1)\n",
    "            S = S[i+1:]  # S = 00(1212)\n",
    "            if '(' not in S:\n",
    "                if S:\n",
    "                    ans += Fraction(int(S), 10 ** len(S))\n",
    "                return ans\n",
    "\n",
    "            i = S.index('(') # i = 2\n",
    "            if i:\n",
    "                ans += Fraction(int(S[:i]), 10 ** i) # Fraction(0, 10 ** 2)\n",
    "            S = S[i+1:-1] # S = [3:] = 1212\n",
    "            j = len(S) # j = 4\n",
    "            ans += Fraction(int(S), 10**i * (10**j - 1)) # Fraction(1212, 10 ** 2 * (10 ** 4 - 1))\n",
    "            return ans\n",
    "\n",
    "        return convert(S) == convert(T)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def handle(self, s):\n",
    "        p = s.find('(')\n",
    "        if p != -1:\n",
    "            cycle = s[p+1:-1]\n",
    "            s = s[:p] + cycle * 15\n",
    "        return s\n",
    "    def isRationalEqual(self, s: str, t: str) -> bool:\n",
    "        s = self.handle(s)\n",
    "        t = self.handle(t)\n",
    "        return abs(float(s) - float(t)) < 0.00000001"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def isRationalEqual(self, s: str, t: str) -> bool:\n",
    "\n",
    "        # newli = []\n",
    "        # for li in [s, t]:\n",
    "        def foo(li: str):\n",
    "            # print('---- ', li)\n",
    "            if len(li.split('(')) > 1:\n",
    "                float_part, xh_part = li.split('(')\n",
    "            else:\n",
    "                float_part = li.split('(')[0]\n",
    "                xh_part = '0'\n",
    "            float_part = float_part if '.' in float_part else f\"{float_part}.\"\n",
    "            xh_part = xh_part.replace(')', '')\n",
    "            # print(float_part, xh_part)\n",
    "\n",
    "            if len(xh_part) > 1:\n",
    "                i = 1\n",
    "                while i <= len(xh_part)/2:\n",
    "                    if xh_part[0] == xh_part[i]:\n",
    "                        tmp = [True if len(x) == 0 else False for x in xh_part.split(xh_part[0:i])]\n",
    "                        if all(tmp):\n",
    "                            xh_part = xh_part[0:i]\n",
    "                            break\n",
    "                    i += 1\n",
    "                    continue\n",
    "\n",
    "            while float_part[-1] == xh_part[-1]:\n",
    "                float_part = float_part[:-1]\n",
    "                # xh_part = xh_part[::-1]\n",
    "                xh_part = f\"{xh_part[-1]}{xh_part[:-1]}\"\n",
    "            if xh_part == '9':\n",
    "                # print(f\"[debug] {float(float_part)}, \", 10**(-len(float_part.split('.')[1])), float(float_part) + 10**(-len(float_part.split('.')[1])))\n",
    "                # tmp_float_part = f\"{float(float_part) + 10**(-len(float_part.split('.')[1]))}\"\n",
    "                tmp_float_part = f\"{int(float_part.replace('.', '')) + 1}\"\n",
    "                tmp_float_part = tmp_float_part.zfill(\n",
    "                    max(len(tmp_float_part), len(float_part)-1)\n",
    "                    )\n",
    "                tmp_len = len(float_part.split('.')[1])\n",
    "                # print(f'[debug] {tmp_float_part}, {tmp_len}')\n",
    "                float_part = f\"{tmp_float_part[:(len(tmp_float_part)-tmp_len)]}.{tmp_float_part[(len(tmp_float_part)-tmp_len):]}\"\n",
    "                float_part = float_part if float_part[-2:] != '.0' else float_part[:-1]\n",
    "                xh_part = '0'\n",
    "                \n",
    "            return f\"{float_part}{xh_part}\"\n",
    "            \n",
    "        return foo(s) == foo(t)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def isRationalEqual(self, s: str, t: str) -> bool:\n",
    "        from fractions import Fraction\n",
    "        def parse(in_str):\n",
    "            if '.' in in_str:\n",
    "                inter_part, dec_part = in_str.split('.')[0], in_str.split('.')[1]\n",
    "                ans = Fraction(int(inter_part), 1)\n",
    "                if len(dec_part) == 0:\n",
    "                    return ans\n",
    "                if '(' not in dec_part:\n",
    "                    ans += Fraction(int(dec_part), 10 ** len(dec_part))\n",
    "                    return ans\n",
    "                else:\n",
    "                    before, after = dec_part.split('(')[0], dec_part.split('(')[1][:-1]\n",
    "                    if len(before) > 0:\n",
    "                        ans += Fraction(int(before), 10 ** len(before))\n",
    "                    ans += Fraction(int(after), 10 ** len(before) * (10 ** len(after) - 1))\n",
    "                    return ans\n",
    "            else:\n",
    "                return Fraction(int(in_str), 1)\n",
    "    \n",
    "        return parse(s) == parse(t)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "from fractions import Fraction\n",
    "\n",
    "class Solution(object):\n",
    "    def isRationalEqual(self, S, T):\n",
    "        def convert(S):\n",
    "            # 对于不包含小数点的整数\n",
    "            if '.' not in S:\n",
    "                return Fraction(int(S), 1)\n",
    "            \n",
    "            # 分离整数和小数部分\n",
    "            i = S.index('.')\n",
    "            ans = Fraction(int(S[:i]), 1)\n",
    "            S = S[i+1:]\n",
    "            \n",
    "            # 如果没有括号\n",
    "            if '(' not in S:\n",
    "                if S:\n",
    "                    ans += Fraction(int(S), 10 ** len(S))\n",
    "                return ans\n",
    "\n",
    "            # 有括号，处理重复小数部分\n",
    "            i = S.index('(')\n",
    "            if i:\n",
    "                ans += Fraction(int(S[:i]), 10 ** i)\n",
    "            S = S[i+1:-1]\n",
    "            j = len(S)\n",
    "            ans += Fraction(int(S), 10**i * (10**j - 1))\n",
    "            \n",
    "            return ans\n",
    "\n",
    "        # 比较两个有理数是否相等\n",
    "        return convert(S) == convert(T)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "from fractions import Fraction\n",
    "\n",
    "class Solution:\n",
    "    def isRationalEqual(self, s: str, t: str) -> bool:\n",
    "        def convert(S):\n",
    "            if '.' not in S:\n",
    "                return Fraction(int(S), 1)\n",
    "            i = S.index('.')\n",
    "            ans = Fraction(int(S[:i]), 1)\n",
    "            S = S[i+1:]\n",
    "            if '(' not in S:\n",
    "                if S:\n",
    "                    ans += Fraction(int(S), 10 ** len(S))\n",
    "                return ans\n",
    "            \n",
    "            i = S.index('(')\n",
    "            if i:\n",
    "                ans += Fraction(int(S[:i]), 10 ** i)\n",
    "            S = S[i+1:-1]\n",
    "            j = len(S)\n",
    "            ans += Fraction(int(S), 10 ** i * (10 ** j - 1))\n",
    "            return ans\n",
    "        return convert(s) == convert(t)"
   ]
  }
 ],
 "metadata": {},
 "nbformat": 4,
 "nbformat_minor": 2
}
